package com.modelscope.ai.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.modelscope.ai.domain.dto.UserDto;
import com.modelscope.ai.domain.dto.UserLoginDto;
import com.modelscope.ai.domain.dto.UserQueryCriteria;
import com.modelscope.ai.domain.entity.User;
import com.modelscope.ai.domain.enums.AppHttpCodeEnum;
import com.modelscope.ai.domain.mapstruct.UserMapstruct;
import com.modelscope.ai.domain.vo.OpenIdVo;
import com.modelscope.ai.domain.vo.UserVo;
import com.modelscope.ai.exception.BusinessException;
import com.modelscope.ai.mapper.UserMapper;
import com.modelscope.ai.service.UserService;
import com.modelscope.ai.utils.AssertUtil;
import com.modelscope.ai.utils.JwtUtils;
import com.modelscope.ai.utils.RandomString;
import io.netty.util.internal.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.parameters.P;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author 20346
 * @description 针对表【user】的数据库操作Service实现
 * @createDate 2023-12-17 11:26:08
 */
@Slf4j
@Transactional
@RequiredArgsConstructor
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {


    final UserMapstruct userMapstruct;
    final PasswordEncoder passwordEncoder;

    private final JwtUtils jwtUtils;
    //token过期时间
    private static final Integer TOKEN_EXPIRE_DAYS = 5;
    //token续期时间
    private static final Integer TOKEN_RENEWAL_DAYS = 2;


    // 判断
    public QueryWrapper<User> getQuery(UserQueryCriteria criteria) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.lambda().eq(criteria.getUid() != null, User::getId, criteria.getUid());
        return userQueryWrapper;
    }

    @Override
    public Page<UserVo> queryAll(UserQueryCriteria userQueryCriteria) {
        // 用来返回所有用户信息，便于测试
        Page<User> page = page(
                new Page<>(userQueryCriteria.getPageNum(), userQueryCriteria.getPageSize()),
                getQuery(userQueryCriteria)
        );
        Page<UserVo> voPage = new Page<>(userQueryCriteria.getPageNum(), userQueryCriteria.getPageSize(), page.getTotal());
        List<UserVo> userVoList = userMapstruct.toVO(page.getRecords());
        voPage.setRecords(userVoList);
        log.info("user queryAll-->{}", voPage);
        return voPage;
    }


    @Override
    public void updateUser(UserDto userDto) {
        log.info("修改用户:{}", userDto);
        AssertUtil.isNotEmpty(userDto.getId(), "id不能为空");
        User update = getById(userDto.getId());
        AssertUtil.isNotEmpty(update, "id不存在");
        // 姓名
        if (StringUtils.isNotEmpty(userDto.getUsername())) {
            update.setUsername(userDto.getUsername());
        }
        // 电话
        if (StringUtils.isNotEmpty(userDto.getPhone())) {
            update.setPhone(userDto.getPhone());
        }
        // 修改头像
        if (StringUtils.isNotEmpty(userDto.getAvatar())) {
            update.setAvatar(userDto.getAvatar());
        }

        // 性别
        if (userDto.getSex() != null) {
            update.setSex(userDto.getSex());
        }

        updateById(update);
    }

    @Override
    public void deleteUser(Long uid) {
        removeById(uid);
    }

    @Override
    public UserVo queryById(Long uid) {
        User user = getById(uid);
        return userMapstruct.toVO(user);
    }


    /**
     * 校验token是不是有效
     *
     * @param token
     * @return
     */
    @Override
    public boolean verify(String token) {
        Long uid = jwtUtils.getUidOrNull(token);
        log.info("LoginServiceImpl  从token获取到的 uid-->{}", uid);
//        if (uid == null) {
//            return false;
//        }
        return uid != null;
//        String key = RedisKey.getKey(RedisKey.USER_TOKEN_STRING, uid);
//        String realToken = RedisUtils.getStr(key);
//        return Objects.equals(token, realToken);//有可能token失效了，需要校验是不是和最新token一致
    }


    @Override
    public String login(UserLoginDto userLoginDto) {

        String username = userLoginDto.getUsername();
        String password = userLoginDto.getPassword();
        log.info("username:{},password:{}", username, password);
        User user = getBaseMapper().selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        if (user == null) {
            throw new BusinessException(AppHttpCodeEnum.ACCOUNT_NOT_EXIST);
        }
        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new BusinessException(AppHttpCodeEnum.WRONG_PASSWORD);
        }
        Long uid = user.getId();
        //获取用户token
        return jwtUtils.createToken(uid);
    }


    @Override
    public Long getValidUid(String token) {
        boolean verify = verify(token);
        Long uid = verify ? jwtUtils.getUidOrNull(token) : null;
        log.info("getUid-->{}", uid);
        return uid;
    }

    @Override
    public OpenIdVo openid(String openid) {
        User save = lambdaQuery().eq(User::getOpenId, openid).one();
        OpenIdVo openIdVo = new OpenIdVo();
        openIdVo.setOpenid(openid);
        // 如果不存在，则表示是新用户
        if (Objects.isNull(save)) {
            // 生成新用户
            save = new User();
            save.setOpenId(openid);
            save.setSex(1);
            String username = RandomString.getRandomNumber(12);
            save.setUsername(username);
            save.setAvatar("https://fakerlove.oss-cn-beijing.aliyuncs.com/pic/3.jpg");
            save.setPassword(passwordEncoder.encode("123456"));
            save(save);
            openIdVo.setIsNewUser(true);
            openIdVo.setUsername(username);
        } else {
            openIdVo.setIsNewUser(false);
            openIdVo.setUsername(save.getUsername());
        }
        openIdVo.setUid(save.getId());
        openIdVo.setToken(jwtUtils.createToken(save.getId()));
        return openIdVo;
    }


    @Override
    public void register(UserDto userDto) {
        log.info("注册信息:{}", userDto);
        // 注册用户信息
        User user = userMapstruct.toEntity(userDto);

        User one = lambdaQuery().eq(User::getUsername, user.getUsername()).one();
        AssertUtil.isEmpty(one, "用户名已经存在");
        User one1 = lambdaQuery().eq(User::getPhone, user.getPhone()).one();
        AssertUtil.isEmpty(one1, "手机号已经存在");
        // 设置密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        save(user);
    }


}




